<?php
/**
 * Created by PhpStorm.
 * User: zhu
 * Date: 2016/10/19
 * Time: 21:50
 */

namespace Lavender;


use Forxx\RedisCache;

class SessionStorage
{

    private $_sessionKey = '';
    protected $forget_time_key = '_et';
    protected $is_initd = false;
    protected $data = null;

    /**
     * session 最长存储时间
     */
    const MAX_EXIST_TIME = 15552000;

    /**
     * session 默认存储时间
     */
    const DEFAULT_EXIST_TIME = 3600;

    /**
     * @param $key
     */
    public function __construct($key, $forget_time_key = '')
    {
        if(!empty($key))
        {
            $pre_key = Core::get_config('const','session_storage_pre_key');
            $this->_sessionKey = $pre_key.$key;
        }
        if (!empty($forget_time_key)) {
            $this->forget_time_key = $forget_time_key;
        }
    }

    /**
     * 初始化数据
     */
    protected function init()
    {
        if (!$this->is_initd) {
            $this->is_initd = true;
            if(empty($this->_sessionKey))
            {
                return;
            }
            $now = time();
            $data = RedisCache::instance()->get($this->_sessionKey);
            if (!empty($data)) {
                if (isset($data[$this->forget_time_key]) && $data[$this->forget_time_key] > $now) {
                    $this->data = $data;
                } else {
                    RedisCache::instance()->delete($this->_sessionKey);
                }
            } else {
                RedisCache::instance()->delete($this->_sessionKey);
            }
        }
    }

    public function getForgetTimeKey()
    {
        return $this->forget_time_key;
    }

    public function setForgetTimeKey($key)
    {
        if(empty($key))
        {
            return ;
        }
        $this->forget_time_key = $key;
    }

    /**
     * 替换整个数据
     * @param $data
     * @param null $forget_time
     * @return bool
     */
    public function save_data($data, $forget_time = null)
    {
        if(empty($this->_sessionKey))
        {
            return;
        }
        $exist_time = $this->get_expired_time($forget_time);
        $this->data = $data;
        $this->data[$this->forget_time_key] = $exist_time + time();
        if ($exist_time > 0) {
            RedisCache::instance()->set($this->_sessionKey, $this->data, $exist_time);
        }
        return true;
    }

    public function update_data($data, $forget_time = null)
    {
        if(empty($this->_sessionKey))
        {
            return;
        }
        $origin = $this->get_data();
        $this->data = array_merge($origin, $data);
        $exist_time = $this->get_expired_time($forget_time);
        $this->data[$this->forget_time_key] = $exist_time + time();
        RedisCache::instance()->set($this->_sessionKey, $this->data, $forget_time);
    }

    public function get_expired_time($forget_time = null)
    {
        $forget_time = intval($forget_time);
        if(empty($forget_time))
        {
            $forget_time = $this->get($this->forget_time_key);
        }
        $now = time();
        if($forget_time > $now)
        {
            return $forget_time - $now;
        }
        if($forget_time > self::MAX_EXIST_TIME)
        {
            return self::DEFAULT_EXIST_TIME;
        }
        return $forget_time;
    }

    public static function set_raw($key,$val,$expired){
        RedisCache::instance()->set($key, $val, $expired);
    }

    public static function get_raw($key){
        return  RedisCache::instance()->get($key);
    }

    public function get_data()
    {
        if(empty($this->_sessionKey))
        {
            return [];
        }
        $this->init();
        return $this->data;
    }

    public function get($key)
    {
        if(empty($this->_sessionKey))
        {
            return;
        }
        $this->init();
        if (isset($this->data[$key])) {
            return $this->data[$key];
        }
        return null;
    }

    public function destroy()
    {
        if(empty($this->_sessionKey))
        {
            return;
        }
        RedisCache::instance()->delete($this->_sessionKey);
    }
}